#include "algo_spray.h"

// 算法头文件
#include "spray/sprayAlgo.h"

#include <unistd.h>

#include "util.h"
#include "modbus-srv.h"

/* Anti-warning macro... */
#define UNUSED(V) ((void) V)

struct spray_param {
    int binary_th_low;
    int warn_th;
    int pts[8]; 
    int detection_period;  // 检测周期，单位帧
    int shoot_num; // 检测周期内，喷淋开的次数
    int shoot_threshold; // 确认喷淋开的阈值
    int frame_index; // 当前帧序号。收到外部信号时，序号开始计数
    //int detection_delaytime; //检测延迟时间
    int start_compu; // 开始计算的信号
} sprayparam;

/**
 * @brief 
 * 
 * @param algo 
 * @return int 0成功 非0失败 如果初始化失败，loop会终止
 */
int init_spray(void* algo)
{
    UNUSED(algo);

    //两个区域，如果只需要一个只需要把坐标写成一样的
    //int roi[8] = {980, 405, 30, 341, 975, 15, 60, 360}; // 运河
    //int roi[8] = {895, 395, 80, 520, 895, 395, 80, 520}; // 唐口东
    int roi[8] = {895, 395, 80, 520, 825, 560, 150, 70}; // 唐口东
    //int roi[8] = {1460, 520, 80, 320, 1460, 520, 80, 320}; // 唐口西


    sprayparam.binary_th_low = 3;
    //sprayparam.warn_th = 200;
    sprayparam.warn_th = 300;
    sprayparam.detection_period = 600;
    sprayparam.shoot_num = 0;
    sprayparam.shoot_threshold = 30;
    sprayparam.start_compu = 0;
    //sprayparam.detection_delaytime = 0;
    sprayparam.frame_index = 0;
    for (int i=0; i<8; i++) sprayparam.pts[i] = roi[i];
    __log_mesg("warn-th=%d, roi =[%d,%d,%d,%d],[%d,%d,%d,%d]\n", sprayparam.warn_th, sprayparam.pts[0],sprayparam.pts[1],sprayparam.pts[2],sprayparam.pts[3],
    sprayparam.pts[4],sprayparam.pts[5],sprayparam.pts[6],sprayparam.pts[7]);

    spraySetRoi(roi,sizeof(roi)/sizeof(int));
    return 0;
}

void* compute_spray(void* algo, unsigned char* data, int width, int height)
{
    if (is_beam_signal_set()) {
        sprayparam.start_compu = 1;
        sprayparam.frame_index = 0;
        //__log_mesg("Compute start and reset shoot_num to 0.\n");
        //spraySetRoi(NULL, 0); //测试语句，让算法内部输出自身统计结果
        sprayparam.shoot_num = 0;
        reset_beam_signal();
        //reset_spray_alarm();
    }

    if (!sprayparam.start_compu) {
        return NULL;
    }

    //if (sprayparam.frame_index == 250) {
    //    __save_image(data, width, height, NULL);
    //}

    SprayResult* res = sprayCalculaton(data, width, height, sprayparam.binary_th_low, sprayparam.warn_th);
    return res;
}

//void debug_spray(unsigned char* data, int width, int height);
void* analysis_spray(void* input)
{
    SprayResult* res = (SprayResult*)input;
    
    ++sprayparam.frame_index;

    int alarm = 0; // 0表示没有结果
    if (res->type != spray_none) ++sprayparam.shoot_num;

    if (sprayparam.frame_index == sprayparam.detection_period) {
        if (sprayparam.shoot_num < sprayparam.shoot_threshold) {
            alarm = 2; // 喷淋没开，报警
            __log_mesg("Detection result=>spray off(shoot-num=%d)\n",sprayparam.shoot_num);
        } else {
            alarm = 1; // 喷淋开了
            __log_mesg("Detection result=>spray on(shoot-num=%d)\n",sprayparam.shoot_num);
        }
        sprayparam.start_compu = 0;
        sprayparam.frame_index = 0;
        sprayparam.shoot_num = 0;
    }
    
    sprayFreeResult(res);
    return alarm;
}

int response_spray(void* algo, void* input)
{
    UNUSED(algo);

    int alarm = (int)input;
    // alarm值可能等于0,1,2,等于0有两种情况
    // 0=>在检测周期类，但是无结果
    // 0=>不在检测周期类
    // 1=> 喷淋开了
    // 2=> 喷淋没开

    if (alarm != 0) {
        if (alarm == 2) {
            set_spray_alarm();
        } else if (alarm == 1) {
            reset_spray_alarm();
        }
        sleep(2);
        fill_spray_alarm(); //平台需求
    }

    return alarm;
}


void destroy_spray(void* algo)
{
    UNUSED(algo);
    sprayFree();
}